# 定义一个简单的类
# 1. 类与对象的基本语法
class Dog:
    # 构造方法
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age

    # 实例方法
    def bark(self):
        return f"{self.name} 在汪汪叫！"

    def get_info(self):
        return f"我叫{self.name}，今年{self.age}岁"


# 创建对象（实例化）
my_dog = Dog("旺财", 3)
print(my_dog.bark())  # 输出：旺财 在汪汪叫！
print(my_dog.get_info())  # 输出：我叫旺财，今年3岁

#2. 面向对象的四大支柱
# 封装（Encapsulation）
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self._balance = balance  # 受保护的属性（约定）
        self.__account_number = "123456"  # 私有属性

    # 公共接口来访问私有数据
    def get_balance(self):
        return self._balance

    def deposit(self, amount):
        if amount > 0:
            self._balance += amount

    def withdraw(self, amount):
        if 0 < amount <= self._balance:
            self._balance -= amount
            return amount
        return 0


account = BankAccount("张三", 1000)
account.deposit(500)
print(account.get_balance())  # 输出：1500

# 继承（Inheritance）
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass  # 抽象方法


class Cat(Animal):  # 继承
    def speak(self):  # 方法重写
        return "喵喵~"

    def climb_tree(self):  # 扩展功能
        return "爬树中..."


class Dog(Animal):
    def speak(self):
        return "汪汪！"


# 多态的体现
animals = [Cat("咪咪"), Dog("旺财")]
for animal in animals:
    print(f"{animal.name}: {animal.speak()}")

#多态（Polymorphism）
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height


class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2


# 多态：不同对象对同一方法有不同的实现
shapes = [Rectangle(5, 3), Circle(2)]
for shape in shapes:
    print(f"面积: {shape.area()}")  # 相同的接口，不同的实现

from abc import ABC, abstractmethod


class Shape(ABC):  # 抽象基类
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass


class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2

    def perimeter(self):
        return 4 * self.side


# shape = Shape()  # 错误！不能实例化抽象类
square = Square(5)
print(square.area())  # 输出：25


class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value

    @property
    def fahrenheit(self):
        return self._celsius * 9 / 5 + 32


temp = Temperature(25)
print(temp.celsius)  # 25
print(temp.fahrenheit)  # 77.0
temp.celsius = 30  # 使用 setter


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):  # 重载 + 运算符
        return Vector(self.x + other.x, self.y + other.y)

    def __str__(self):  # 重载 str() 函数
        return f"Vector({self.x}, {self.y})"

    def __len__(self):  # 重载 len() 函数
        return 2


v1 = Vector(2, 3)
v2 = Vector(1, 4)
v3 = v1 + v2  # 调用 __add__
print(v3)  # 调用 __str__，输出：Vector(3, 7)
print(len(v1))  # 调用 __len__，输出：2

class Flyable:
    def fly(self):
        return "我在飞！"

class Swimmable:
    def swim(self):
        return "我在游泳！"

class Duck(Flyable, Swimmable):  # 多重继承
    def speak(self):
        return "嘎嘎！"

duck = Duck()
print(duck.fly())   # 我在飞！
print(duck.swim())  # 我在游泳！

# 验证"一切皆对象"
print(type(5))           # <class 'int'> - 数字是对象
print(type("hello"))     # <class 'str'> - 字符串是对象
print(type([1, 2, 3]))   # <class 'list'> - 列表是对象
print(type(lambda x: x)) # <class 'function'> - 函数是对象
print(type(int))         # <class 'type'> - 类本身也是对象！

# 所有对象都有属性和方法
name = "Python"
print(name.upper())      # 字符串对象的方法
print(name.__class__)    # 所有对象都有 __class__ 属性